package csv

import javax.sql.DataSource
import javax.xml.ws.BindingProvider;

import org.grails.datastore.gorm.finders.MethodExpression.IsNotNull;
import org.junit.internal.runners.statements.FailOnTimeout;

import groovy.sql.Sql
import groovy.ui.text.FindReplaceUtility.FindAction;
import sugarbind_input.*
import app.*


public class CsvParserPathogen {
	
	List<String> arrayErrors = new ArrayList<String>()
	Set bindingErrors = new HashSet()
	
	ObjFinder finder = new ObjFinder()
	DefaultValue d = new DefaultValue()	
	
	def parse
		
	def idx=0
	def shift=0	
	
	static int ARTICLE_IMPORT_REF = 0
	static int AGENT = 1
	static int AGENT_TAXONOMY_ID = 2
	static int AGENT_SYNONYM = 3
	static int AGENT_TYPE = 4
	static int AGENT_NOTES = 5
	static int AGENT_PROPERTY = 6
	static int LECTIN_SUPPORT = 7
	static int LECTIN = 8
	static int LECTIN_UNIPROT = 9
	static int GENE = 10
	static int CERMAV_REF = 11
	static int GLYCOPROTEIN_UNIPROT_ID = 12
	
	static int GLYCOCONJUGATE_TYPE = 13
	static int LIGAND_TYPE = 14	
	static int IUPAC = 15
	static int AGLYCON = 16
	
	static int LIGAND_ABBREV = 17
	static int LIGAND_NAME = 18
	static int LIGAND_SYNONYM = 19
	static int LIGAND_NOTES = 20
	static int BINDING_STRENGTH = 21
	static int BINDING_NOTES = 22
	static int METHOD = 23
	static int LIGAND_SOURCE = 24
//	static int SOURCE_ORGANISM = 23
	static int DISEASE = 25
	static int DISEASE_SYNONYM = 26
	static int HOST_STUDIED = 27
	static int HOST_NOTES = 28
	static int HOST_TAXON_ID = 29
	static int AFFECTED_AREA_STUDIED = 30
	static int SYNDROME_SYMPTOM = 31

	
	
	
	
	
//	static int SYSTEM = 0
//	static int ORGAN = 1
//	static int TISSUE = 2
//	static int CELL = 3
//	static int SYNTHETIC = 4

	/*----------------------------------------*/

	
	
	CsvParserPathogen(String filepath)
	{
		println("CsvParser : Pathogen" + filepath)
		parse = new File(filepath).readLines()[idx+1..-1]//[108..110]//[1..-1]
		csvParsePath()
	}
	
	/*Constructor to access parsing methods from other classes*/
	CsvParserPathogen()
	{
		
	}
	
	def csvParsePath()
	{
		 
//---------------------------------------------------------------------- 
		 def article
	 	 
		 def agent_Type
		 def agent
		 def supportData
		 def supportType
		 def support
		 def lectin
		 def structure
		 def methods
		 def bindingStrength
		 def hosts
		 def affectedAreas
		 def sourceOrganism
		 def sources
		 def ligandTypes
		 def glycoconjugateType
		 def aglycon
		 def ligand
		 def binding
		 def diseases
		 def diseaseSynonyms
		 def symptoms
		 
		 def start = System.currentTimeMillis()
		 def mid 
		 def end
		 
		 parse.each {line ->
			 idx++
			 println("====================")
			 println("Row $idx")
			 println("====================")
			
			 mid = System.currentTimeMillis()
			 
			 line.splitEachLine(d.tokenSemiColon) { fields ->
				 
			 
		 article = finder.findArticle(fields[ARTICLE_IMPORT_REF])		
		 println("article: $article") 
		 
		 csvParseStructure(fields[IUPAC]) //1
		 structure =finder.findStructure(fields[IUPAC])
		 println("structure: $structure")
		 
		 println("ligandTypesLine : ${fields[LIGAND_TYPE]}")
		 csvParseLigandTypes(fields[LIGAND_TYPE],true) //+
		 
		 ligandTypes =finder.findLigandTypes(fields[LIGAND_TYPE])
		 println("ligandTypes : $ligandTypes")
		 
		 csvParseGlycoconjugateType(fields[GLYCOCONJUGATE_TYPE]) //1
		 glycoconjugateType =finder.findGlycoconjugateType(fields[GLYCOCONJUGATE_TYPE])
		 println("glycoconjugateType : $glycoconjugateType")
		 
		 csvParseAglycon(fields[AGLYCON]) //1
		 aglycon =finder.findAglycon(fields[AGLYCON])
		 println("aglycon : $aglycon")
		 
//		 csvParseMethods(fields[METHOD],true) //+
//		 methods =finder.findMethods(fields[METHOD])
//		 println("methods: $methods")
/*++*/	 sources = csvParseSources(fields[LIGAND_SOURCE]) //++
			println("sources : $sources")
//		 
		 csvParseLigand(fields[LIGAND_NAME],fields[LIGAND_ABBREV],fields[LIGAND_NOTES],fields[GLYCOPROTEIN_UNIPROT_ID],
						 ligandTypes, structure, sources, glycoconjugateType, aglycon)
		  ligand =finder.findLigand(fields[LIGAND_NAME], fields[LIGAND_ABBREV] ,structure)
		  println("ligand : $ligand")
		csvParseLigandSynonyms(fields[LIGAND_SYNONYM], ligand, true)
		 
 		 csvParseAgentType(fields[AGENT_TYPE]) //1		  
		  agent_Type =finder.findAgentType(fields[AGENT_TYPE])
		  println("agent_Type: $agent_Type")
 		 agent =  csvParseAgent(fields[AGENT],fields[AGENT_NOTES],fields[AGENT_TAXONOMY_ID], '', agent_Type, article)
		  println("agent: $agent")
/*+*/ 	 
		 csvParseAgentSynonyms(fields[AGENT_SYNONYM], agent) //+
		 
		 
		 csvParseAgentProperties(fields[AGENT_PROPERTY],agent, true) //1
//		 def supportName = csvParseLectinSupportData(fields[LECTIN_SUPPORT],agent)
//		 support =finder.findLectinSupport(supportName,agent)		  		 
		 	
		 supportData = csvParseLectinSupportData(fields[LECTIN_SUPPORT])//,agent,true)
		 csvParseLectinSupportType(supportData[0])
		  supportType =finder.findLectinSupportType(supportData[0])
//		 println("lectin support type main : ${supportType} ");
		 support = csvParseLectinSupport(supportData[1], supportType, agent)
		 println("lectin support main : ${support} ");
		 
		 
		 lectin = csvParseLectin(fields[LECTIN],fields[GENE],fields[CERMAV_REF], support, ligand) //1
		  println("lectin: $lectin");
/*+*/	 csvParseLectinUniprots(fields[LECTIN_UNIPROT], lectin, true) //+
 
 		 
/*+*/	 csvParseMethods(fields[METHOD],true) //+
		  methods =finder.findMethods(fields[METHOD])
		  println("methods: $methods")
		  
		 csvParseBindingStrength(fields[BINDING_STRENGTH]) //1
		  bindingStrength =finder.findBindingStrength(fields[BINDING_STRENGTH])
		  println("bindingStrength: $bindingStrength")

		 symptoms = csvParseSymptoms(fields[SYNDROME_SYMPTOM]) //+
		  println("symptoms: $symptoms")
		  
/*+*/	 diseases = csvParseDiseases(fields[DISEASE],symptoms) //+
		  println("diseases: $diseases")		  
		  
/*+*/	 diseaseSynonyms = csvParseDiseaseSynonyms(diseases,fields[DISEASE_SYNONYM]) //+
		  println("diseaseSynonyms: $diseaseSynonyms")
///*+*/	 def symptoms = csvParseDiseaseSymptoms(fields[DISEASE],fields[SYNDROME_SYMPTOM], true) //+
		 
 		 csvParseHosts(fields[HOST_STUDIED],fields[HOST_NOTES],fields[HOST_TAXON_ID]) //1
		  hosts =finder.findOrganisms(fields[HOST_STUDIED],fields[HOST_NOTES])
		  println("hosts: $hosts")
		  		 
/*++*/	 csvParseAffectedAreas(fields[AFFECTED_AREA_STUDIED], hosts) //++ fields[AFFECTED_AREA_STUDIED]
		  affectedAreas =finder.findAreas(fields[AFFECTED_AREA_STUDIED], hosts)
		  println("affectedAreas : $affectedAreas")
//		 csvParseSourceOrganism(fields[SOURCE_ORGANISM])
//		  sourceOrganism =finder.findOrganism(fields[SOURCE_ORGANISM],'')
//		  println("sourceOrganism : $sourceOrganism")
///*++*/	 csvParseSources(fields[LIGAND_SOURCE],ligand) //++ 
// 		  sources =finder.findAreas(fields[LIGAND_SOURCE], sourceOrganism)
//		  println("sources : $sources")
 		 
//		  csvParseLigandType(fields[LIGAND_TYPE])
//		  ligandType =finder.findLigandType(fields[LIGAND_TYPE])
//		  println("ligandType : $ligandType")
// 		 csvParseLigand(fields[GLYCOCONJUGATE_NAME],fields[GLYCOCONJUGATE_ABBREV],fields[LIGAND_NOTES],fields[GLYCOPROTEIN_UNIPROT_ID],
//			  			ligandType, structure, sources)  
//		  ligand =finder.findLigand(fields[GLYCOCONJUGATE_NAME],structure)
//		  println("ligand : $ligand")
//		 csvParseLigandSynonyms(fields[LIGAND_SYNONYM], ligand, true)
 
		 //FIXME
/*+*/	 binding = csvParseBinding(
			fields[BINDING_NOTES], 
			finder.findDatabase("SB"), 
			ligand,
			bindingStrength, 
			lectin, 
			methods, article)
		 //binding =finder.findBinding(ligand,finder.findDatabase("SB"), lectin, fimbria, fields[BINDING_NOTES])	 
		println("binding : $binding")

		 
/*+*/	csvParseDiseaseAreaAgents(
			diseases,
			affectedAreas,			
			agent)
//		println("diseaseAreaAgents : $diseases, $affectedAreas, $agent")
 			//line processing time
			end = System.currentTimeMillis()			
		 }
			
			
			
			println("Entry Processing time : " + (end-mid)/1000 + "[s]")
			println("Avg entry Processing time : " + (end-start)/(1000*idx) + "[s]")
			println("Total Processing time : " + (end-start)/1000 + "[s]")
		 }
		 
		 println("Errors : ")
		 for(int i = 0; i<arrayErrors.size();i++)
		 {
			 if(arrayErrors.get(i)!=null)
			 {
				 println("${arrayErrors.get(i)}")
			 }
		 }
		 
		 println("Binding errors : ")
		 println(bindingErrors)
		 
		 
		 
	}
	
		
	//-------------------
	//Parsers
	//-------------------
	def csvParseAgentType(String agentTypeName) //1
	{
		def obj = new Agent_Type(
			agent_Type_Name: Utils.importFormat(agentTypeName)
			)
		obj.validate()
		obj.save(flush: true)
		return obj
	}
	// pathogen -> agent : auto ref
//	def csvParseAgent(String agentNamesLine, String agentNotes, String taxonomyId, String agentRef, Agent_Type agentType, Article article) //1
//	{
//		def agentNames = agentNamesLine.split(d.semicolon, -1);
//		int j=0
//		
//		def agentObj
//		
//		while(j<agentNames.length)
//		{
//			
//                        /*get the last significant element of the hierarchy*/
//			
//			def name 
//			if(j==1)
//			{
//				name = Utils.importFormatLowerCase(agentNames[j])
//			}
//			else
//			{
//				name = Utils.importFormat(agentNames[j])
//			}
//			
//			
//			def obj
//			if(agentNames[j].isEmpty() || agentNames[j]==null)
//			{
//				name = d.UNKNOWN
//			}
//			
////			println("agent name : " + name)
//			
//			//first element of hierarchy, with no parent
//			if(j==0)
//			{
//                            println(j + " / " + name + "/=======================")
//				obj = Agent.findByAgent_Name(name)
//				System.out.println("csvParseAgent1 : $j $name");
//				if(obj==null)
//				{
//					obj = new Agent(
//						agent_Name: name
//						)
//				}
//				agentObj = obj;
//				
//			}
//			//hierarchical information, but not the last element (strain or toxin)
//			if(j>0 && j!=agentNames.length-1)
//			{
//                            println(j + " / " +name + " / " + agentObj + "/=======================")
//				println("knownAgentParent to find : " + agentNamesLine +"/"+ j-1 +"/"+ article) 
//				def knownAgentParent = finder.findAgent(agentNamesLine, j-1, article)
//                                println("knownAgentParent : " + knownAgentParent) 
//				
////				if(Utils.importFormat(name) == Utils.importFormat(d.UNKNOWN) || knownAgentParent == null)
//				if(name.equalsIgnoreCase(d.UNKNOWN_STRAIN)) //|| knownAgentParent == null)				
//				{
//                                    println("d.UNKNOWN_STRAIN : " + d.UNKNOWN_STRAIN)                                    
//
//                                    Agent parent = finder.findAgent(Utils.importFormat(agentNames[j-1]),article)
//                                    println("parent : " + parent)
//
//                                    Agent agent = finder.findAgent(name, parent, article)
//                                    obj = new Agent(
//                                            agent_Name: name,
//                                            agent_Parent:parent
//                                            )
//				}
//				else
//				{
////					println("findAgent( ${name}, ${agentNames[j-1]}, null)")
//					obj = knownAgentParent
//				}
//				agentObj = obj
//                                println(agentObj)
//			}
//			
//			//strain or toxin information
//			if( j==agentNames.length-1)
//			{
//                            println(j + " / " + name + "/=======================")
//                            def grandParent = Agent.findByAgent_NameIlike(Utils.importFormat(agentNames[j-2]))
////                            def parent = Agent.findByAgent_NameIlikeAndAgent_Parent(Utils.importFormat(agentNames[j-1]), grandParent)
//                            def parent = agentObj
//                
//                            println("ancestors : $grandParent $parent")
//                            
//				println("__________________")
//				println(obj)
//                                def knownAgent=finder.findAgent(agentNamesLine, j, article)				
//				println("knownAgent1 : " + knownAgent)
//				
//				def parentAgent=finder.findAgent(agentNamesLine,j-1,article)
//				println("parentAgent1 : " + parentAgent)
//				
//				def taxid = null
//				if (!taxonomyId.isEmpty())
//					{
//						taxid = Integer.valueOf(Utils.importFormat(taxonomyId))
//					}
//				println("csvParseAgent3 : $j $name $agentType");
//				if(knownAgent == null)
//				{
//					obj = new Agent(
//						agent_Name: name,
//						agent_Parent: parentAgent, 					
//						taxonomy_Id: taxid,
//						agent_Type:agentType,
//						article_Import_Ref:article.article_Import_Ref,
//						agent_Notes : Utils.importFormat(agentNotes),
//						agent_Ref : Utils.importFormat(agentRef)
//						)
////					println("knownAgent1 : " + obj)
//				}
//				else
//				{
//	//					println("findAgent( ${name}, ${agentNames[j-1]}, null)")
//					obj = knownAgent//findAgent(Utils.importFormat(name), Utils.importFormat(agentNames[j-1]), null)
//	//					println("found agent : $obj")
//	//				
//				}
//			
//			}
//		obj.validate()
//				
//		try
//		{
//			obj.save(flush:true, failOnError:true)
////			println("!!saved!! $obj")
//		}
//		catch(Exception ex)
//		{
//			System.err.println(ex.getMessage());
//		}
//	
//                println("agent OBJ1 : " + obj)
//		println("agent OBJ2 : " + agentObj)
//            
//		agentObj = obj
//			
//		j++
//		
//		}
//		
//		return agentObj
//	}
	
        def csvParseAgent(String agentNamesLine, String agentNotes, String taxonomyId, String agentRef, Agent_Type agentType, Article article) //1
	{
		def agentNames = agentNamesLine.split(d.semicolon, -1);
		int j=0
		
		def agentObj
		
		while(j<agentNames.length)
		{
			
                        /*get the last significant element of the hierarchy*/
			
			def name 
                        /*set and format agent name value*/
			if(j==1)
			{
				name = Utils.importFormatLowerCase(agentNames[j])
			}
			else
			{
				name = Utils.importFormat(agentNames[j])
			}
			
			
			def obj
//			if(agentNames[j].isEmpty() || agentNames[j]==null)
//			{
//				name = d.UNKNOWN
//			}			
//			println("agent name : " + name)
			
			//first element of hierarchy, with no parent
			if(j==0 && j!=agentNames.length-1)
			{
                            println(j + " / " + name + "/=======================")
				obj = Agent.findByAgent_Name(name)
				System.out.println("csvParseAgent1 : $j $name");
				if(obj==null)
				{
					obj = new Agent(
						agent_Name: name
						)
				}
				agentObj = obj;
				
			}
			//hierarchical information, but not the last element (strain or toxin)
			if(j>0 && j!=agentNames.length-1)
			{
                            println(j + " / " +name + " / " + agentObj + "/=======================")
//				println("knownAgentParent to find : " + agentNamesLine +"/"+ j-1 +"/"+ article) 
				//def knownAgentParent = finder.findAgent(agentNamesLine, j-1, article)
//                                println("knownAgentParent : " + knownAgentParent)
//                                println("knownAgentParent : " + knownAgentParent)
				
//				if(Utils.importFormat(name) == Utils.importFormat(d.UNKNOWN) || knownAgentParent == null)

                                Agent parent = agentObj
                                
				/*check if agent name is "Unknown Strain"*/
                                if(name.equalsIgnoreCase(d.UNKNOWN_STRAIN)) //|| knownAgentParent == null)				
				{
                                    println("d.UNKNOWN_STRAIN : " + d.UNKNOWN_STRAIN)                                    

                                    
                                    
                                    Agent agent = finder.findAgent(name, parent, article)
                                    println("agent : $agent, parent : $parent, article : $article")
                    
                                    if(agent == null)
                                    {
                                        obj = new Agent(
                                            agent_Name: name,
                                            agent_Parent:parent,
                                            agent_Ref : Utils.importFormat(agentRef)
                                            )
                                    }
                                    else
                                    {
                                        obj = agent
                                    }
				}
				else
				{
                                    Agent agent = Agent.findByAgent_NameIlikeAndAgent_Parent(name, parent)
                                    if(agent == null)
                                    {
                                        obj = new Agent(
                                            agent_Name: name,
                                            agent_Parent:parent
                                            )
                                    }
                                    else
                                    {
                                        obj = agent
                                    }
//                                  println("findAgent( ${name}, ${agentNames[j-1]}, null)")
//                                  obj = knownAgentParent
				}
//				agentObj = obj
//                                println(agentObj)
			}
			
			//strain or toxin information (-> j=2 if strain, 3 if toxin, or 0 if toxin with no parent info)
			if( j==agentNames.length-1)
			{
                            println(j + " / " +name + " / " + "/=======================")
                            println("parent : " + agentObj )
//                            def grandParent = Agent.findByAgent_NameIlike(Utils.importFormat(agentNames[j-2]))
//                            def parent = Agent.findByAgent_NameIlikeAndAgent_Parent(Utils.importFormat(agentNames[j-1]), grandParent)
                            def parent = agentObj
                            
                            Integer taxid = null
                            if (!taxonomyId.isEmpty())
                                {
                                        taxid = Integer.valueOf(Utils.importFormat(taxonomyId))
                                }
                
//                            println("ancestors : $grandParent $parent")
                            
				println("__________________")
				println(obj)
                                
                            /*check if agent name is "Unknown Strain"*/
                                if(name.equalsIgnoreCase(d.UNKNOWN_STRAIN)) //|| knownAgentParent == null)				
				{
                                    println("d.UNKNOWN_STRAIN : " + d.UNKNOWN_STRAIN)                                    

//                                    Agent parent = agentObj
                                    
                                    Agent knownAgent = finder.findAgent(name, parent, article)
                                    
				
                                    if(knownAgent == null)
                                    {
                                        obj = new Agent(
                                            agent_Name: name,
                                            agent_Parent:parent, 					
                                            taxonomy_Id: taxid,
                                            agent_Type:agentType,
                                            article_Import_Ref:article.article_Import_Ref,
                                            agent_Notes : Utils.importFormat(agentNotes),
                                            agent_Ref : Utils.importFormat(agentRef)
                                            )
                                    }
                                    else
                                    {
                                        obj = knownAgent
                                    }
				}
				else
				{
                                    Agent knownAgent = Agent.findByAgent_NameIlikeAndAgent_Parent(name, parent)
                                    if(knownAgent == null)
                                    {
                                        obj = new Agent(
                                            agent_Name: name,
                                            agent_Parent: parent, 					
                                            taxonomy_Id: taxid,
                                            agent_Type:agentType,
                                            article_Import_Ref:article.article_Import_Ref,
                                            agent_Notes : Utils.importFormat(agentNotes),
                                            agent_Ref : Utils.importFormat(agentRef)
                                            )
                                    }
                                    else
                                    {
                                        obj = knownAgent
                                    }
//                                  println("findAgent( ${name}, ${agentNames[j-1]}, null)")
//                                  obj = knownAgentParent
				}
                                
//                                def knownAgent=finder.findAgent(agentNamesLine, j, article)				
//				println("knownAgent1 : " + knownAgent)
				
//				def parentAgent=finder.findAgent(agentNamesLine,j-1,article)
//				println("parentAgent1 : " + parentAgent)
				
//				def taxid = null
//				if (!taxonomyId.isEmpty())
//					{
//						taxid = Integer.valueOf(Utils.importFormat(taxonomyId))
//					}
//				println("csvParseAgent3 : $j $name $agentType");
//				if(knownAgent == null)
//				{
//					obj = new Agent(
//						agent_Name: name,
//						agent_Parent: parentAgent, 					
//						taxonomy_Id: taxid,
//						agent_Type:agentType,
//						article_Import_Ref:article.article_Import_Ref,
//						agent_Notes : Utils.importFormat(agentNotes),
//						agent_Ref : Utils.importFormat(agentRef)
//						)
////					println("knownAgent1 : " + obj)
//				}
//				else
//				{
//	//					println("findAgent( ${name}, ${agentNames[j-1]}, null)")
//					obj = knownAgent//findAgent(Utils.importFormat(name), Utils.importFormat(agentNames[j-1]), null)
//	//					println("found agent : $obj")
//	//				
//				}
			
			}
		obj.validate()
				
		try
		{
			obj.save(flush:true, failOnError:true)
//			println("!!saved!! $obj")
		}
		catch(Exception ex)
		{
			System.err.println(ex.getMessage());
		}
	
                println("agent OBJ1 : " + obj)
		println("agent OBJ2 : " + agentObj)
            
		agentObj = obj
			
		j++
		
		}
		
		return agentObj
	}
	
	def csvParseAgentSynonyms(String synonymsLine, Agent agent) //+
	{
		def synonyms = (Utils.importFormat(synonymsLine)).split(d.semicolon)
		
		for (int i = 0; i<synonyms.length ;i++) 
		{
				csvParseAgentSynonym(synonyms[i], agent)
		}				
	}
	
	
	def csvParseAgentSynonym(String agentSynonymName, Agent agent) //+
	{
		def obj = new Agent_Synonym(
			agent_Synonym_Name: Utils.importFormat(agentSynonymName) ,
			agent: agent
		)
		obj.validate()
		obj.save(flush: true)
		return obj
	}
	

	
	def csvParseAgentProperties(String agentPropertiesLine, Agent agent, boolean saveObj) //1
	{
		def props = (Utils.importFormat(agentPropertiesLine)).split(d.tokenSemiColon)
		if(saveObj && props!=null)	
		{
			for (int i = 0; i<props.length ;i++) {
				def props_value = props[i].split(d.comma,-1)
//				System.out.println("props_value : ${props[i]} / "+ props_value.length); 
					def type = Utils.importFormat(props_value[0])
					def value = d.UNKNOWN
					if(props_value.length==2)
					{
						value = Utils.importFormat(props_value[1])
					}
					csvParseAgentPropertyType(type)
					
					def typeObj =finder.findAgentPropertyType(type)
//					System.out.println("props_type : ${props_value[0]} / "+ props_value.length);
					
					if(typeObj != null)
					{
						csvParseAgentProperty(value, typeObj, agent)
//						System.out.println("props : $value | $typeObj | $agent");  
					}
			}
		}	
	}
	
	def csvParseAgentPropertyType(String agentPropertyTypeName) //1
	{
		def obj = new Agent_Property_Type(
			agent_Property_Type_Name: Utils.importFormat(agentPropertyTypeName)
		)
		obj.validate()
		obj.save(flush:true)
		return obj
	}
	
	def csvParseAgentProperty(String agentPropertyValue, Agent_Property_Type agentPropertyType, Agent agent) //1
	{
//		System.out.println("AgentProperty value:$agentPropertyValue, type:$agentPropertyType, agents:$agent, isSupport:$isSupport");
		if(agentPropertyValue==null || agentPropertyValue.isEmpty())
		{
			agentPropertyValue = d.UNKNOWN
		}
			
		def obj = new Agent_Property(
			agent_Property_Value: Utils.importFormat(agentPropertyValue) ,
			agent_Property_Type: agentPropertyType
		)

		obj.validate()
		obj.save(flush: true)		
		
		def agentProperty =finder.findAgentProperty(obj.agent_Property_Value, agentPropertyType)

		try
		{
			agentProperty.addToAgents(agent)
			agentProperty.validate()
			agentProperty.save(flush: true)
		}
		catch(Exception ex)
		{
			System.err.println(ex.getMessage());
		}

//		println("Agent_Property : $agentProperty ${agentProperty.id}")		
		return obj
	}
	
	def csvParseLectinSupportData(String lectinSupportData)//, Agent agent, boolean saveObj)
	{
		def support = lectinSupportData.split(d.comma)

		def type = support[0]
//		println("lectinSupport : $support / length ${support.length}");

		def name = d.UNKNOWN
		if(support.length==2)
		{
			name = support[1]
		}
		String[] supportData = [type,name]
		
//		println("supportData : $supportData")
		return supportData
	}
	
	def csvParseLectinSupportType(String lectinSupportTypeName) //1
	{
//		println("support type $lectinSupportTypeName")
		def obj = new Lectin_Support_Type(
			lectin_Support_Type_Name: Utils.importFormat(lectinSupportTypeName)
		)
//		println("support type obj1 $obj")
		obj.validate()
		obj.save(flush:true)
//		println("support type obj2 $obj")
		return obj
	}
	
	def csvParseLectinSupport(String lectinSupportName, Lectin_Support_Type lectinSupportType, Agent agent)//, boolean saveObj) //1
	{	
		
//		System.out.println("csvParseLectinSupport name:$lectinSupportName, type:$lectinSupportType, agents:$agent");
		if(lectinSupportName==null || lectinSupportName.isEmpty())
		{
			lectinSupportName = d.UNKNOWN
		}
		def lectinSupport =finder.findLectinSupport(lectinSupportName, agent, lectinSupportType)
		def obj
		if(lectinSupport==null)
		{	
			obj = new Lectin_Support(
				lectin_Support_Name: Utils.importFormat(lectinSupportName) ,
				agent: agent,
				lectin_Support_Type: lectinSupportType
			)
//		println("lectin_Support_Name obj : ${obj.lectin_Support_Name}")
//		println("agent obj : ${obj.agent}")
//		println("lectin_Support_Type obj : ${obj.lectin_Support_Type}")
		
			obj.validate()
			try
			{
				println(obj.errors)
				obj.save(flush:true, failOnError:true)
			}
			catch(Exception ex)
			{
				println(ex.getMessage())
			}
			lectinSupport = obj
		}
		
//		println("!!lectinSupport : $lectinSupport")
		return lectinSupport
	}
	
	def csvParseLectin(String lectinName, String geneName, String cermavRef, Lectin_Support lectinSupport, Ligand ligand) //1
	{
		//fields[LECTIN]		
		def lectin
		
		//if name = d.UNKNOWN, search by name, support and ligand (look for lectin already associated to a binding in the db)
		def testUnknown = d.UNKNOWN.toLowerCase().equals(Utils.importFormat(lectinName).toLowerCase())

		if(testUnknown) //Unknown
		{
//			println("lectin name UNKNOWN : $lectinName")
			lectin =finder.findLectinBindings(lectinName, lectinSupport, ligand)
		}				
		else //else search only by name and support
		{
//			println("lectin name NOT UNKNOWN: $lectinName")
			lectin =finder.findLectinNoBindings(lectinName,lectinSupport)
		}
		
		def obj		
		//if not exist in db then create
		if(lectin==null)
		{
			obj = new Lectin(
				lectin_Name: Utils.importFormat(lectinName),
				gene_Name:Utils.importFormatNoCase(geneName),
				cermav_Ref:Utils.importFormat(cermavRef),
				lectin_Support:lectinSupport
			)
				
//			println("parseLectin NEW lectin : $lectin")
			obj.validate()
			obj.save(flush: true, failOnError:true)
//			println("parseLectin NEW SAVED lectin : $lectin")
			lectin = obj
		}
		return lectin
	}
	
	
//	def csvParseLectin2(String lectinName, String geneName, String cermavRef, Lectin_Support lectinSupport, Ligand ligand) //1
//	{
//		//look for lectin already associated to a binding in the db
//		def lectin
//		 
//			lectin =finder.findLectinBindings(lectinName, lectinSupport, ligand)
//			println("findLectinBindings : $lectin")
//		
//		def obj
//		
//		//if not exist in db then create
//		if(lectin==null)
//		{
//			obj = new Lectin(
//				lectin_Name: Utils.importFormat(lectinName),
//				gene_Name:Utils.importFormatNoCase(geneName),
//				cermav_Ref:Utils.importFormat(cermavRef),
//				lectin_Support:lectinSupport
//			)
//				
//			println("parseLectin NEW lectin : $lectin")
//			obj.validate()
//			obj.save(flush: true, failOnError:true)
////			println("parseLectin NEW SAVED lectin : $lectin")
//			lectin = obj	
//		}
//		
//		//lectin =finder.findLectinNoBindings(fields[LECTIN],support)
//		if(lectin==null)
//		{
//			lectin =finder.findLectinNoBindings(fields[LECTIN],support)
//		}
////		println("lectin: $lectin");
//		println("LECTIN : " + lectin)
//		return lectin
//	}
	
	def csvParseLectinUniprots(String uniprotsLine, Lectin lectin, saveObj) //+
	{
		def data = (Utils.importFormat(uniprotsLine))
		if (data != null){data = data.split(d.tokenSemiColon)}
		
		if(saveObj)
		{
			for (int i = 0; i<data.length ;i++) {
				csvParseLectinUniprot(data[i],lectin)
			}
		}	
	}
	
	def csvParseLectinUniprot(String uniprotId, Lectin lectin) //+
	{
		def obj
		if(lectin != null && uniprotId != null && !uniprotId.isEmpty())
		{
			obj = new Lectin_Uniprot(
				uniprot_Id: Utils.importFormat(uniprotId) ,
				lectin: lectin
			)
			obj.validate()
			obj.save(flush: true)
		}	
		return obj
	}
	
	def csvParseStructure(String iupac) //1
	{
		def obj = new Structure(
			iupac: Utils.importFormat(iupac)
		)
		obj.validate()
		obj.save(flush:true)
		return obj
	}
	
	def csvParseMethods(String methodsLine, boolean saveObj) //+
	{
		def data = (Utils.importFormat(methodsLine))
		if (data != null){data = data.split(d.tokenSemiColon)}
		
		if(data != null)	
		{
			for (int i = 0; i<data.length ;i++) 
			{
				csvParseMethod(data[i],saveObj)
			}
		}
		return data				
	}
	
	def csvParseMethod(String methodName, boolean saveObj)
	{
		def obj = new Method(
			method_Name: Utils.importFormat(methodName)
		)
		obj.validate()
		if(saveObj)
		{
			obj.save(flush:true)
		}
		return obj
	}
	
	def csvParseBindingStrength(String bindingStrength) //1
	{
		def obj = new Binding_Strength(
			binding_Strength_Name: Utils.importFormat(bindingStrength)
		)
		obj.validate()
		obj.save(flush:true)
		return obj
	}
	
	def csvParseDiseases(String diseasesLine, HashSet<Symptom> symptoms)
	{
		List<Disease> diseases = new ArrayList<Disease>()
		println("diseases : $diseases ${diseases.size()}")
		
		def data = (Utils.importFormat(diseasesLine))
		if (data != null){data = data.split(d.tokenSemiColon)}
		
		if(data != null)
		{
			for (int i = 0; i<data.length ;i++) {
				Disease disease = csvParseDisease(data[i])
				
				if(disease != null)
				{						
					diseases.add(disease)
				}	
			}
		}
		
		if(diseases.size()==0 && (symptoms.size()>0))
		{
			Disease.findByDisease_Name(Utils.importFormat(d.UNKNOWN))
		}
		
		for(Disease disease : diseases)
		{	
			for(Symptom symptom : symptoms)
			{
//				println("disease : ${disease} ${disease.id} / symptom : ${symptom} ${symptom.id}")
				try
				{
//					if(symptom.diseases[disease]!=null)
//					{
//					disease.addToSymptoms(symptom)
					symptom.addToDiseases(disease)
//					}
				}
				catch(Exception ex)
				{
					System.err.println(ex.getMessage())
				}	
			}
		}
		
//		println("diseases : ${diseases} ")
		return diseases
	}
	
	def csvParseDisease(String diseaseName) //+
	{
		def disease =finder.findDisease(diseaseName)
		if(disease == null)
		{
			def obj = new Disease(
				disease_Name: Utils.importFormat(diseaseName)
			)
			obj.validate()
			obj.save(flush:true)
			disease= obj
		}		
		return disease
	}
	
	def csvParseDiseaseSynonyms(ArrayList<Disease> diseases, String diseaseSynonymNamesLine) //+
	{
		
		def synonyms = (Utils.importFormat(diseaseSynonymNamesLine))
		if (synonyms != null){synonyms = synonyms.split(d.tokenSemiColon)}
		
		if(synonyms != null  && diseases != null)
		{
			for (int i = 0; i<synonyms.length ;i++) {
				for(int j = 0; j <diseases.size();j++){
					csvParseDiseaseSynonym(synonyms[i], diseases.get(j))
				}
			}
		}
	}	
	
	def csvParseDiseaseSynonym(String diseaseSynonymName, Disease disease) //+
	{
		def obj = new Disease_Synonym(
			disease_Synonym_Name: Utils.importFormat(diseaseSynonymName),
			disease:disease
		)
		obj.validate()
		obj.save(flush:true)
//		println("diseaseSynonymName : $diseaseSynonymName disease")
		return obj
	}
	
	
	def csvParseSymptoms(String symptomStudiedNamesLine) //+
	{
		HashSet<Symptom> symptoms = new HashSet<Symptom>()
		 
		def data = (Utils.importFormat(symptomStudiedNamesLine))
		if (data != null){data = data.split(d.tokenSemiColon)}
		
		if(data != null )
		{
			for (int i = 0; i<data.length ;i++) {
				Symptom symptom = csvParseSymptom(data[i])
				symptoms.add(symptom)
			}
		}
//		println("symptoms : $symptoms")
		return symptoms
	}
	
	def csvParseSymptom(String symptomName) //+
	{
		def symptom = Symptom.findBySymptom_Name(Utils.importFormat(symptomName))
		if(symptom == null)
		{
			def obj = new Symptom(
				symptom_Name: Utils.importFormat(symptomName)
	//			disease:disease
			)
			symptom = obj
			
			symptom.validate()
			symptom.save(flush:true, failOnError : true)
//			println("symptom : $symptom ${symptom.id}")
		}	
		
		symptom.validate()
		symptom.save(flush:true)		
//		println("symptom : $symptom")

		return symptom
	}
	
	def csvParseHosts(String organismNamesLine,String organismNotes, String taxonomyId) //1
	{
		HashSet<Organism> hosts = new HashSet<Organism>()
		
	   def data = (Utils.importFormat(organismNamesLine))
	   if (data != null)
	   {
		   data = data.split(d.comma)
	   }
	   
	   if(data != null )
	   {
		   for (int i = 0; i<data.length ;i++) 
		   {
			   Organism host = csvParseHost(data[i], organismNotes, taxonomyId)			   
			   hosts.add(host)
		   }
	   }
//	   println("hosts : $hosts")
	   return hosts
	}
	
	
	def csvParseHost(String organismName,String organismNotes, String taxonomyId) //1
	{
//		println("host (organismName, organismNotes): $organismName , $organismNotes")
		def obj = new Organism(
			organism_Name: Utils.importFormat(organismName),
			organism_Notes: Utils.importFormat(organismNotes),
			taxonomy_Id: Utils.importFormat(taxonomyId)
		)
		obj.validate()
		obj.save(flush: true)
//		println("host : $obj ")
		return obj
	}
	
	def csvParseAffectedAreas(String affectedAreasLine,Set<Organism> organisms) //++ fields[AFFECTED_AREA_STUDIED]
	{
		def areas = new ArrayList<Area>()
		
		Set<Organism> hosts = organisms
		if(hosts == null)
		{			
			hosts= new HashSet<Organism>()
			hosts.add(d.unknownHost)
		}
		
		def data = (Utils.importFormat(affectedAreasLine))
//		println("affectedAreasLine : $affectedAreasLine ")
		if (data != null )
		{
			data = data.split(d.pipe)
//			println("data : $data")
//			areas = new String[data.length]
//			println("areas : $areas ${areas.length}")
			
			for (int i = 0; i<data.length ;i++) {
				for (Organism host : hosts)
				{
//					areas[i]=csvParseAffectedArea(data[i],host)
					areas.add(csvParseAffectedArea(data[i],host))
//					println("areas[i] : ${areas[i]}")
				}
			}
		}
		else
		{
			if (organisms != null )
			{
				for (Organism organism : organisms)
				{
					areas.add(csvParseAffectedArea(d.UNKNOWN,organism))
				}
			}	
		}
//		println("areas : $areas ${areas.length}")
		return areas
	}
	
	def csvParseAffectedArea(String affectedArea,Organism organism)
	{
		Area area
		String areaName =""
		def areaString = affectedArea.split(d.semicolon,-1)
//		println("areaString : $areaString ${areaString.length}")
		int j=0		
		
		while(j<areaString.length && areaString[j]!="" && areaString[j]!=null )
		{
			/*get the last significant element of the hierarchy*/
			areaName=areaString[j]
			
			//any but first area in the hierarchy
			if(j>0)
			{
				area = new Area(
					area_Name: Utils.importFormat(areaString[j]),
					area_Type: Area_Type.findById(j+1),
					organism: organism,
					area_Parent: Area.findByArea_Name(Utils.importFormat(areaString[j-1]))
				)
//				println("area with parent : $area ")
			}
			//first area in the hierarchy
			else
			{
			area = new Area(
				area_Name: Utils.importFormat(areaString[j]),
				area_Type: Area_Type.findById(j+1),
				organism: organism,
				)
//			println("area no parent : $area ")
			}
			area.validate()		
			area.save(flush:true)			
			j++
		}
//		println("areaName : $areaName ")
//		return areaName
		return area
	}
	
	def csvParseSources(String sourcesLine) //++
	{
		if(sourcesLine!=null && !sourcesLine.isEmpty())
		{
//			println("sourcesLine : $sourcesLine")
			HashSet sources = new HashSet<Source>()
			
			def data = (Utils.importFormat(sourcesLine))
			if (data != null)
			{
				data = data.split(d.pipe)
				for (int i = 0; i<data.length ;i++) {
					Source source = csvParseSource(data[i])
//					println("source : $source")
					if(source!=null)
					{
						sources.add(source)
					}	
				}
			}

			return sources
//			println("sources : $sources")
		}	
	}
	
	
	
	def csvParseSource(String sourceLine)
	{	
//		println("sourceLine : $sourceLine")
		
		def data = (Utils.importFormat(sourceLine))
		String supplier = null
		
		def obj
		
		if (data != null && !data.isEmpty() && !(data.toLowerCase().matches(Utils.regex(d.NOT_APPLICABLE.toLowerCase()))))
		{
			def source
			def organism		
			def source_Type
			
			data = data.split(d.semicolon)
//			println("source data : $data")
			try
			{
				supplier = Utils.importFormat(data[1])
			}
			catch(Exception ex)
			{
				System.err.println(ex.getMessage())
			}
			
			data = data[0].split(d.comma)
			String sourceName = null
			String organismName = null
			
			try
			{
				sourceName = Utils.importFormat(data[0])
				organismName = Utils.importFormat(data[1])
			}
			catch(Exception ex)
			{
				System.err.println(ex.getMessage())
			}
			
			
			if(sourceName == null || sourceName.isEmpty())
			{
				sourceName = d.UNKNOWN				
			}
			
			if(organismName != null)
			{
				organism = csvParseSourceOrganism(organismName)
			}
			
			
			if(sourceName != null && !sourceName.toLowerCase().equals(d.NOT_APPLICABLE.toLowerCase()))
			{
//				println("sourceName : ${sourceName.toLowerCase()} ${Utils.regex(d.NOT_APPLICABLE.toLowerCase())}")
				if(sourceName.toLowerCase().matches(Utils.regex(d.LABEL_SEMISYNTH.toLowerCase())) || sourceName.toLowerCase().matches(Utils.regex(d.LABEL_SEMISYNTH.replace('-', '').toLowerCase())))
				{
					source_Type = d.sourceTypeSemiSynth				
				}
				else if(sourceName.toLowerCase().matches(Utils.regex(d.LABEL_SYNTHETIC.toLowerCase())))
				{
					source_Type = d.sourceTypeSynthetic		
				}
				else
				{
					source_Type = d.sourceTypeBiological
				}
				source =finder.findSource(sourceName, source_Type, organism, supplier)
//				println("source found : $source")
			}
			if(source == null)
			{
				source = new Source(
					source_Name : sourceName,
					supplier : supplier,
					source_Type : source_Type
					)
				if(organism!=null)
				{
					source.organism = organism					
				}
				source.validate()
				source.save(flush:true, failOnError:false)
			}		
			
//			println("source : $source")	
			obj = source
		}		
		return obj
	}
	
	def csvParseSourceOrganism(String organismName)
	{		
		def organism = Organism.findByOrganism_NameAndOrganism_Notes(Utils.importFormat(organismName),"")
//		println("organism : " + organism)
		if(organism == null)
		{
//			println("organism_Name : " + Utils.importFormat(organismName))
			def obj = new Organism(
				organism_Name: Utils.importFormat(organismName),
				organism_Notes: ""
			)
//			println("organism : " + obj)
			obj.validate()
			obj.save(flush: true, failOnError:true)
//			println("NEW organism : $obj")
			organism = obj
		}	
//		println("organism : $organism")	
		return organism
	}
	
	def csvParseSource(String sourceName, Organism organism, String supplier, Source_Type sourceType)
	{		
		Source source =finder.findSource(sourceName, sourceType, organism, supplier)		
		if(source == null)
		{
			def obj = new Source(
				source_Name: Utils.importFormat(sourceName),
				supplier: Utils.importFormat(supplier),
				source_Type: sourceType,
				organism:organism
				)
			obj.validate()
			obj.save(flush:true)
			
			source=obj
		}
		return source
	}
	
	def csvParseGlycoconjugateType(String glycoconjugateTypeName) //1
	{
		if(glycoconjugateTypeName != null && !glycoconjugateTypeName.isEmpty())
		{
		def obj = new Glycoconjugate_Type(
			glycoconjugate_Type_Name: Utils.importFormat(glycoconjugateTypeName)
			)
		obj.validate()
		obj.save(flush: true)
		return obj
		}
	}
	
	def csvParseAglycon(String aglyconName) //1
	{
		if(aglyconName != null && !aglyconName.isEmpty())
		{
		def obj = new Aglycon(
			aglycon_Name: Utils.importFormat(aglyconName)
			)
		obj.validate()
		obj.save(flush: true)
		return obj
		}
	}
	
	def csvParseLigandTypes(String ligandTypesLine, boolean saveObj) //+
	{
		def data = (Utils.importFormat(ligandTypesLine))
		if (data != null){data = data.split(d.tokenSemiColon)}
		
		if(data != null)
		{
			for (int i = 0; i<data.length ;i++) {
				csvParseLigandType(data[i],saveObj)
			}
		}
		return data
	}
	
	def csvParseLigandType(String ligandTypeName, boolean saveObj)
	{
		def obj = new Ligand_Type(
			ligand_Type_Name: Utils.importFormat(ligandTypeName)
		)
		obj.validate()
		if(saveObj)
		{
//			println("ligand type : ${obj.ligand_Type_Name}")
			obj.save(flush:true)
		}
		return obj
	}
	
	/********************/
	def csvParseLigand(String fullName, String abbrevName,String ligandNotes,String ligandRef, HashSet<Ligand_Type> ligandTypes, Structure structure, HashSet<Area> sources, Glycoconjugate_Type glycoconjugateType, Aglycon aglycon)
	{
		
		def obj =finder.findLigand(fullName, abbrevName, structure)
//		println("findLigand : $obj")
		
		if((fullName!=null && !fullName.isEmpty()) || obj==null)
		{
			obj = new Ligand(
				full_Name: Utils.importFormat(fullName),
				abbrev_Name: Utils.importFormat(abbrevName),
				ligand_Notes: Utils.importFormat(ligandNotes),
				ligand_Ref: Utils.importFormat(ligandRef),
				
				structure: structure,
				glycoconjugate_Type: glycoconjugateType,
				aglycon: aglycon
			)
		}
		
//		println("csvParseLigand? : $obj")
		obj.validate()
		obj.save(flush:true)
//		println("csvParseLigand?? : $obj")
		
		def ligand =finder.findLigand(fullName, abbrevName, structure) 
//		println("ligand !: $ligand")
		
		if(ligand != null)
		{
			if(ligandTypes != null && !(ligandTypes.isEmpty()) && !(ligandTypes.contains(null)))
			{
	//			println("Binding methods : $methods + ${methods.size()}")
				ligand.setLigand_Types(ligandTypes)
			}
			
			
			if(sources != null && !(sources.isEmpty()) && !(sources.contains(null)))
			{				
//				println("Ligand sources : $sources + ${sources.size()}")
				ligand.setSources(sources)
			}			
			ligand.validate()
			ligand.save(flush:true)
		}
//		println("ligand !!: $ligand")
		return ligand
	}
	
	def csvParseLigandSynonyms(String synonymsLine, Ligand ligand, boolean saveObj)
	{
//		println("synonymsLine : $synonymsLine")
//		println("ligand : $ligand")
		def synonyms = (Utils.importFormat(synonymsLine))
		if (synonyms != null){synonyms = synonyms.split(d.tokenSemiColon)}
		
		if(saveObj && synonyms!= null)
		{
			for (int i = 0; i<synonyms.length ;i++) {
				csvParseLigandSynonym(synonyms[i], ligand)
			}
		}
	}
	
	def csvParseLigandSynonym(String ligandSynonymName, Ligand ligand) //+
	{
		def obj = new Ligand_Synonym(
			ligand_Synonym_Name: Utils.importFormat(ligandSynonymName) ,
			ligand: ligand
		)
		obj.validate()
		obj.save(flush: true)
		return obj
	}
	
	//FIXME	: Add methods and strain in unique constraint!
//	def csvParseBinding(String bindingNotes, Database database, Ligand ligand, Binding_Strength bindingStrength, Lectin lectin, Fimbria fimbria)
	public def csvParseBinding(String bindingNotes, Database database, Ligand ligand, Binding_Strength bindingStrength, Lectin lectin, HashSet<Method> methods, Article article)	
	{
		println(this)
		
		println("----------------------")
		println("binding_Notes: ${Utils.importFormat(bindingNotes)}")
		println("database: $database")
		println("ligand: $ligand")
		//println("agent: $agent")
		println("binding_Strength: $bindingStrength")
		println("lectin: $lectin")
		//println("fimbria: $fimbria")
		println("methods: $methods")
		println("article: $article")
		println("----------------------")
		
		
		def existingBindingArticle =finder.findBinding(lectin,ligand,article)
		def existingBinding =finder.findBinding(lectin,ligand,article)
//		println("existingBindingArticle : " + existingBindingArticle)
		
		
		def obj
		if(existingBinding==null)
		{
			obj = new Binding(
				database: database,
				ligand: ligand,
				//agent: agent,
				binding_Strength: bindingStrength,
				lectin: lectin,
				//fimbria: fimbria,
				//methods: methods,
				binding_Notes: Utils.importFormat(bindingNotes)
		)	
			
			obj.save()
		}
		else
		{
			obj=existingBinding
		}	
			
			
			addBindingArticle(obj,article)				
//			println("Binding methods : $methods ${methods.size()}")
			addBindingMethods(obj, methods)	
			//??obj.addAllToMethods(methods)
		
		
		obj.validate()
//		println(obj.errors)
		if(obj.errors.hasErrors())
		{
			println("${obj.errors.toString()}")
			arrayErrors.add(idx +'\t'+ obj.errors.toString())
		}
		
		if(obj.save(flush: true)==null)
		{
//			println("binding is null: $obj")
		}

		if(idx != obj.id + shift)
		{
			shift= idx - obj.id
			bindingErrors.add(idx)			
		}	
		println("binding : " + obj)
		return obj		
//		println("Database binding found : ${obj}")
	}
	
	def addBindingMethods(Binding binding, HashSet<Method> methods)	
	{
		
			try
			{
                            if(methods != null && !(methods.isEmpty()) && methods.size()!=0 )  //&& !(methods.contains(null))
                            {
				for(Method method : methods)
				{
                                    if(method!=null)
                                    {
					binding.addToMethods(method)
                                    }    
				}	
			
//				def met = methods.toArray()
//
//				for(int j=0;j<met.size();j++)
//				{
//					binding.addToMethods(met[j])	
//				}
                            binding.validate()
                            binding.save(flush: true)
                        }
                    }
			catch(Exception ex)
			{
				System.err.println(ex.getMessage());
			}
                    
                    
                    
				
		
		
	}	
        
        def addBindingArticle(Binding binding, Article article)	
	{
		if(article != null )  //&& !(methods.contains(null))
		{
			try
			{					
                            binding.addToArticles(article)					
			
//				def met = methods.toArray()
//
//				for(int j=0;j<met.size();j++)
//				{
//					binding.addToMethods(met[j])	
//				}
//				
			binding.validate()
                        binding.save(flush: true)	
			}
			catch(Exception ex)
			{
				System.err.println(ex.getMessage());
			}
			
		}
		
	}
	
	def csvParseDiseaseAreaAgents(ArrayList<Disease> diseases, ArrayList<Area> areas , Agent agent) //+
	{
		println("------------------")
		println("csvParseDiseaseAreaAgents")
		println("diseases size : ${diseases.size()}")
		println("areas size : ${areas.size()}")
//		println("agents size : ${agent.size()}")
		
		ArrayList<Disease> di = new ArrayList<Disease>()
		ArrayList<Area> ar = new ArrayList<Area>()
		
		// to create the triplet, create the missing value
		if(diseases.size()!=0 && (areas.size()==0 || areas.get(0)==null))
		{
			Area unknownArea = finder.findArea(d.UNKNOWN, d.unknownHost)
			println("unknownArea : $unknownArea")
			if(unknownArea == null)
			{	csvParseAffectedArea(d.UNKNOWN, d.unknownHost)
				unknownArea = finder.findArea(d.UNKNOWN, d.unknownHost)
			}
			println("unknownArea : $unknownArea")
			ar.add(unknownArea)
		}
		else
		{
			ar = areas	
		}
		
		
		if((diseases.size()==0   || diseases.get(0)==null || diseases.get(0).disease_Name.isEmpty() ) && areas.size() != 0)
		{
			Disease unknownDisease = finder.findDisease(d.UNKNOWN)
			println("unknownDisease : $unknownDisease")
			di.add(unknownDisease)
			println("diseases di: $diseases")
		}
		else
		{
			di = diseases
		}
		
		if(di != null  && ar != null && agent != null)
		{
			
			
			for (int i = 0; i<di.size() ;i++) {
				for(int j = 0; j <ar.size();j++){
					
//					def disease
//					if(d.size()<=1)
//					{
//						disease =finder.findDiseaseUnknown(diseases.get(i).disease_Name)
//					}
//					else
//					{
						def disease = di.get(i)
//					}
						
//					def area =areas[j]
						def area =ar.get(j)
					if(disease!=null && area!=null)
					{
						println("disease, area, agent : $disease, $area, $agent")
						csvParseDiseaseAreaAgent(disease, area, agent)
					}
				}
			}
		}
	}
	
	
	def csvParseDiseaseAreaAgent(Disease disease, Area area, Agent agent) //+
	{
		def obj = new Disease_Area_Agent(
			disease: disease,
			area: area,
			agent: agent
		)
		
		obj.validate()
		obj.save(flush:true)	
		println("disease_Area_Agent : $obj")
		return obj
	}
	

	
	
	/*-----------------------------------------------------------------------------------*/
	/*-----------------------------------------------------------------------------------*/
	/*-----------------------------------------------------------------------------------*/
	/*-----------------------------------------------------------------------------------*/
	/*-----------------------------------------------------------------------------------*/
	/*-----------------------------------------------------------------------------------*/
	
}
